package org.mbds.wolf.seql;


import java.util.ArrayList;
import java.util.List;

import org.mbds.wolf.exception.WolfException;
import org.mbds.wolf.tools.BytesTool;

import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Root;

/**
 * 
 * @author alesas
 *
 */
@Root
public class AppletModel {

	/*
	 * the alias of the SE service (applet)
	 */
	@Attribute
	private String alias;
	
	/*
	 * the AID of the SE service (applet)
	 */
	@Attribute
	private String AID;
	
	/*
	 * the list of available SeQL instructions
	 */
	@ElementList (required=false)
	private List<SeqlModel> instructions;
	
	/*
	 * the list of available data (fields)
	 */
	@ElementList (required=false)
	private List<Data> dataModel;

	/**
	 * Constructor AppletModel
	 */
	public AppletModel() 
	{
		instructions = new ArrayList<SeqlModel>();
		dataModel = new ArrayList<Data>();
	}

	/**
	 * getAlias
	 * @return String
	 */
	public String getAlias() 
	{
		return alias;
	}

	/**
	 * setInstructions
	 * @param instructionsList
	 */
	public void setInstructions(List<SeqlModel> instructionsList) 
	{
		this.instructions = instructionsList;
	}

	/**
	 * setTables
	 * @param dataList
	 */
	public void setTables(List<Data> dataList) 
	{
		this.dataModel = dataList;
	}

	/**
	 * setAlias
	 * @param alias
	 */
	public void setAlias(String alias) 
	{
		this.alias = alias;
	}

	/**
	 * getAID
	 * @return String
	 */
	public String getAID() 
	{
		return AID;
	}

	/**
	 * setAID
	 * @param aID
	 */
	public void setAID(String aID) 
	{
		AID = aID;
	}

	/**
	 * addData
	 * @param data
	 */
	public void addData(Data data) 
	{
		this.dataModel.add(data);
	}

	/**
	 * addInstruction
	 * @param instruction
	 */
	public void addInstruction(SeqlModel instruction) 
	{
		this.instructions.add(instruction);
	}

	/**
	 * getIns
	 * @param seql
	 * @return byte[]
	 * @throws WolfException
	 */
	public byte[] getIns(String seql) throws WolfException 
	{
		for (SeqlModel model : instructions) 
		{
			if (model.getSeqlAlias().equalsIgnoreCase(seql)) 
			{
				try 
				{
					System.out.println("CLA "+ model.getCla() +", INS  " + model.getIns() + ", Instruction " + model.getSeqlAlias());
					return BytesTool.hexStringToByteArray(model.getCla().replace("\\s", "")+model.getIns().replace("\\s", ""));
				} 
				catch (WolfException e) 
				{
					throw e;
				}
			}
		}
		throw new WolfException("AppletModel.getIns: Instruction not found!");
	}

	/**
	 * getInstructions
	 * @return the instructions
	 */
	public List<SeqlModel> getInstructions() 
	{
		return instructions;
	}

	/**
	 * getData
	 * @return the data
	 */
	public List<Data> getData() 
	{
		return dataModel;
	}

	/**
	 * getDataId
	 * @param alias
	 * @return byte
	 * @throws WolfException
	 */
	public byte getDataId(String alias) throws WolfException 
	{
		for (Data model : dataModel) 
		{
			System.out.println("Data ID  " + model.getId() + " Alias " + model.getName());
			if (model.getName().equalsIgnoreCase(alias)) 
			{
				try 
				{
					return BytesTool.hexStringToByteArray(model.getId().replace("\\s", ""))[0];
				} catch (WolfException e) 
				{
					throw e;
				}
			}
		}
		throw new WolfException("AppletModel.getDataId: Data not found!");
	}

	/**
	 * getDataLength
	 * @param alias
	 * @return int
	 * @throws WolfException
	 */
	public int getDataLength(String alias) throws WolfException 
	{
		for (Data model : dataModel) 
		{
			if (model.getName().equalsIgnoreCase(alias)) 
			{
				return model.getLength();
			}
		}
		throw new WolfException("AppletModel.getDataLength: Data not found!");
	}

	/**
	 * toString
	 */
	public String toString() 
	{
		return this.alias;
	}
	
	/**
	 * checkDataBelongToApplet
	 * @param data_list
	 * @param appletModel
	 * @return array byte[] of fields ids
	 * @throws WolfException
	 */
	public byte[] checkDataBelongToApplet(String[] data_list) throws WolfException 
	{
		byte[] resp = new byte[data_list.length];
		int i = 0;
		for (String field : data_list) 
		{
			try 
			{
				resp[i] = getDataId(field);
			} 
			catch (WolfException e) 
			{
				throw e;
			}
			i++;
		}
		return resp;
	}
	
	/**
	 * checkInstructionsBelongToApplet
	 * @param instruction
	 * @return boolean
	 * @throws WolfException
	 */
	public boolean checkInstructionsBelongToApplet(String instruction) throws WolfException {
		if (instruction == null || instruction.trim().length() == 0)
		{
			return false;
		}

		for (SeqlModel model : instructions) 
		{
			if (model.getSeqlAlias().equalsIgnoreCase(instruction.trim()))
			{
				return true;
			}
		}
		return false;
	}
	
	/**
	 * getSeqlType
	 * @param CLA
	 * @param INS
	 * @return String instruction
	 * @throws Exception
	 */
	public String getSeqlType(byte CLA, byte INS) throws Exception
	{
		for (SeqlModel model : instructions) 
		{
			if (model.getCla().equalsIgnoreCase(BytesTool.byteToHexaString(CLA)) && model.getIns().equalsIgnoreCase(BytesTool.byteToHexaString(INS)))
			{
				return model.getSeqlAlias();
			}
		}
		throw new WolfException("SeQL alias not found!: CLA="+BytesTool.byteToHexaString(CLA)+" INS:"+BytesTool.byteToHexaString(INS));
	}
}
